package com.newcoin.xgb.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.api.R;
import com.newcoin.xgb.dto.CancelOrSubmitDto;
import com.newcoin.xgb.dto.GrabAnOrderDto;
import com.newcoin.xgb.dto.QueryParameterDto;
import com.newcoin.xgb.entity.*;
import com.newcoin.xgb.mapper.*;
import com.newcoin.xgb.po.GrabOrderGoodsPo;
import com.newcoin.xgb.po.GrabPageInfoPo;
import com.newcoin.xgb.service.GrabOrderService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

@Service
@Slf4j
public class GrabOrderServiceImpl implements GrabOrderService {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Autowired
    private GrabOrdersRecordMapper grabOrdersRecordMapper;

    @Autowired
    private UsersMapper usersMapper;

    @Autowired
    private GoodsMapper goodsMapper;

    @Autowired
    private GradOrderTimeMapper gradOrderTimeMapper;

    @Autowired
    private AccountMapper accountMapper;

    @Autowired
    private AreaMapper areaMapper;

    @Autowired
    private BonusRecordMapper bonusRecordMapper;


    @Override
    public Result<XgbGrabOrdersRecord> autoOrder(GrabAnOrderDto grabAnOrderDto) throws Exception {
        log.info("grabAnOrderDto={}", grabAnOrderDto);
        Result<XgbGrabOrdersRecord> result = new Result<>();
        if (loginVerification(grabAnOrderDto.getUserId(), grabAnOrderDto.getToken())) {
            result.setCode(401);
            result.setMessage("请登录");
            return result;
        }
        String currentTime = new SimpleDateFormat("HH:mm").format(new Date());
        XgbGradOrderTime xgbGradOrderTime = gradOrderTimeMapper.selectOne(
                new QueryWrapper<XgbGradOrderTime>()
                        .lt("time_start", currentTime)
                        .gt("time_end", currentTime));
        if (xgbGradOrderTime == null) {
            result.setCode(500);
            result.setMessage("不在抢购时段");
            return result;
        }
        XgbUsers users = usersMapper.selectById(grabAnOrderDto.getUserId());
        if (users.getTodayOrderNum() >= 60) {
            result.setCode(500);
            result.setMessage("今日抢单次数已用完");
            return result;
        }
        XgbArea area = areaMapper.selectById(grabAnOrderDto.getAreaId());
        if (area.getLevelCondition() > users.getLevel()) {
            result.setCode(500);
            result.setMessage("理财等级不足,无法抢单");
            return result;
        }
        List<XgbGrabOrdersRecord> xgb = grabOrdersRecordMapper.selectList(new QueryWrapper<XgbGrabOrdersRecord>()
                .eq("user_id", grabAnOrderDto.getUserId())
                .eq("state", 0));
        if (xgb.size() != 0) {
            result.setCode(500);
            result.setMessage("有未提交订单,无法抢单");
            return result;
        }
        XgbAccount account = accountMapper.selectOne(new QueryWrapper<XgbAccount>()
                .eq("user_id", grabAnOrderDto.getUserId()));
        BigDecimal totalAssets = account.getBalance().add(account.getFinancialBalance());
        //if (totalAssets.compareTo(new BigDecimal("0")) <= 0) {
          if (totalAssets.compareTo(new BigDecimal("100")) < 0) {
            result.setCode(500);
            result.setMessage("资产小于100无法抢单哦");
            return result;
        }
        Thread.sleep(1500);
        long goodsCount = goodsMapper.selectCount(new QueryWrapper<XgbGoods>()
                .lt("goods_price", totalAssets));
        XgbGoods good = goodsMapper.selectOne(new QueryWrapper<XgbGoods>()
                .lt("goods_price", totalAssets)
                .last("LIMIT " + getRandom(0L, goodsCount) + ",1"));
       /* BigDecimal proportion = area.getProportion().divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
        BigDecimal bonus = totalAssets.multiply(proportion);
        XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
        xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
        xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
        xgbGrabOrdersRecord.setState(0);
        xgbGrabOrdersRecord.setCommission(bonus);
        xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
        grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);*/
        if (users.getLevel() == 0){
            BigDecimal proportion = new BigDecimal("0.0300").divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
            BigDecimal bonus = totalAssets.multiply(proportion);
            XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
            xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
            xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
            xgbGrabOrdersRecord.setState(0);
            xgbGrabOrdersRecord.setCommission(bonus);
            xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
            grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);

            result.setCode(200);
            result.setMessage("成功");
            result.setData(xgbGrabOrdersRecord);
        }else if(users.getLevel()== 1){
            BigDecimal proportion = new BigDecimal("0.0320").divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
            BigDecimal bonus = totalAssets.multiply(proportion);
            XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
            xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
            xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
            xgbGrabOrdersRecord.setState(0);
            xgbGrabOrdersRecord.setCommission(bonus);
            xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
            grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);

            result.setCode(200);
            result.setMessage("成功");
            result.setData(xgbGrabOrdersRecord);
        }else if(users.getLevel()== 2){
            BigDecimal proportion = new BigDecimal("0.0340").divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
            BigDecimal bonus = totalAssets.multiply(proportion);
            XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
            xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
            xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
            xgbGrabOrdersRecord.setState(0);
            xgbGrabOrdersRecord.setCommission(bonus);
            xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
            grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);

            result.setCode(200);
            result.setMessage("成功");
            result.setData(xgbGrabOrdersRecord);
        }else if(users.getLevel()== 3){
            BigDecimal proportion = new BigDecimal("0.0360").divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
            BigDecimal bonus = totalAssets.multiply(proportion);
            XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
            xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
            xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
            xgbGrabOrdersRecord.setState(0);
            xgbGrabOrdersRecord.setCommission(bonus);
            xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
            grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);

            result.setCode(200);
            result.setMessage("成功");
            result.setData(xgbGrabOrdersRecord);
        }else if(users.getLevel()== 4){
            BigDecimal proportion = new BigDecimal("0.0400").divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
            BigDecimal bonus = totalAssets.multiply(proportion);
            XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
            xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
            xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
            xgbGrabOrdersRecord.setState(0);
            xgbGrabOrdersRecord.setCommission(bonus);
            xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
            grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);

            result.setCode(200);
            result.setMessage("成功");
            result.setData(xgbGrabOrdersRecord);
        }else if(users.getLevel()== 5) {
            BigDecimal proportion = new BigDecimal("0.0420").divide(new BigDecimal("60"), 8, BigDecimal.ROUND_DOWN);
            BigDecimal bonus = totalAssets.multiply(proportion);
            XgbGrabOrdersRecord xgbGrabOrdersRecord = new XgbGrabOrdersRecord();
            xgbGrabOrdersRecord.setGoodsImg(good.getGoodsPic());
            xgbGrabOrdersRecord.setGoodsName(good.getGoodsName());
            xgbGrabOrdersRecord.setState(0);
            xgbGrabOrdersRecord.setCommission(bonus);
            xgbGrabOrdersRecord.setUserId(grabAnOrderDto.getUserId());
            grabOrdersRecordMapper.insert(xgbGrabOrdersRecord);

            result.setCode(200);
            result.setMessage("成功");
            result.setData(xgbGrabOrdersRecord);
        }
            return result;
        }


    @Override
    public Result cancelOrSubmit(CancelOrSubmitDto cancelOrSubmitDto) throws Exception {
        log.info("cancelOrSubmitDto={}", cancelOrSubmitDto);
        Result result = new Result<>();
       if (loginVerification(cancelOrSubmitDto.getUserId(), cancelOrSubmitDto.getToken())) {
            result.setCode(401);
            result.setMessage("请登录");
            return result;
        }
        XgbUsers users = usersMapper.selectById(cancelOrSubmitDto.getUserId());
        if (users.getTodayOrderNum().compareTo(new Integer("60"))>=0){
            result.setCode(500);
            result.setMessage("今日已提交60单,无法继续提交");
            return result;
        }
        XgbGrabOrdersRecord xgbGrabOrdersRecord = grabOrdersRecordMapper.selectById(cancelOrSubmitDto.getOrderId());
        if (xgbGrabOrdersRecord.getState() == 1) {
            result.setCode(500);
            result.setMessage("订单已提交");
            return result;
        }
        int row = grabOrdersRecordMapper.update(null, new UpdateWrapper<XgbGrabOrdersRecord>()
                .eq("id", cancelOrSubmitDto.getOrderId())
                .set("state", 1));
        row = row + accountMapper.update(null, new UpdateWrapper<XgbAccount>()
                .eq("user_id", cancelOrSubmitDto.getUserId())
                .setSql("balance=balance+" + xgbGrabOrdersRecord.getCommission())
                .setSql("order_grab_total_income=order_grab_total_income+" + xgbGrabOrdersRecord.getCommission())
                .setSql("order_grab_static_total_income=order_grab_static_total_income+" + xgbGrabOrdersRecord.getCommission())
                .setSql("order_grab_today_total_income=order_grab_today_total_income+" + xgbGrabOrdersRecord.getCommission())
                .setSql("order_grab_today_static_income=order_grab_today_static_income+" + xgbGrabOrdersRecord.getCommission()));
        if (row != 2) {
            throw new RuntimeException("提交失败");
        }
        XgbBonusRecord bonusRecord = new XgbBonusRecord();
        bonusRecord.setType(1);
        bonusRecord.setUserId(cancelOrSubmitDto.getUserId());
        bonusRecord.setBonusName("抢单收益");
        bonusRecord.setFromId((long) 0);
        bonusRecord.setAmount(xgbGrabOrdersRecord.getCommission());

        String userPath = usersMapper.getUserPath(cancelOrSubmitDto.getUserId());
        String[] split = userPath.split(",");
        for (int i = split.length - 1; i >= 0; i--) {
            XgbBonusRecord br = new XgbBonusRecord();
            if(i == split.length - 1){
                //1级
                if (Long.valueOf(split[i]) == 0){
                    break;
                }
                int i1 = accountMapper.setBalance(xgbGrabOrdersRecord.getCommission().multiply(new BigDecimal("0.16")), Long.valueOf(split[i]));
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Calendar calendar = Calendar.getInstance();
                Date date = calendar.getTime();
                String dateStringParse = sdf.format(date);

                br.setCreateDate(dateStringParse);
                br.setType(4);
                br.setUserId(Long.valueOf(split[i]));
                br.setBonusName("代理分佣");
                br.setFromId(cancelOrSubmitDto.getUserId());
                br.setAmount(xgbGrabOrdersRecord.getCommission().multiply(new BigDecimal("0.16")));
            }else if(i == split.length - 2){
                //2级
                if (Long.valueOf(split[i]) == 0){
                    break;
                }
                int i2 = accountMapper.setBalance(xgbGrabOrdersRecord.getCommission().multiply(new BigDecimal("0.08")), Long.valueOf(split[i]));

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Calendar calendar = Calendar.getInstance();
                Date date = calendar.getTime();
                String dateStringParse = sdf.format(date);

                br.setCreateDate(dateStringParse);

                br.setType(4);
                br.setUserId(Long.valueOf(split[i]));
                br.setBonusName("代理分佣");
                br.setFromId(cancelOrSubmitDto.getUserId());
                br.setAmount(xgbGrabOrdersRecord.getCommission().multiply(new BigDecimal("0.08")));
            }else if(i == split.length - 3){
                //3级
                if (Long.valueOf(split[i]) == 0){
                    break;
                }
                int i3 = accountMapper.setBalance(xgbGrabOrdersRecord.getCommission().multiply(new BigDecimal("0.04")), Long.valueOf(split[i]));

                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Calendar calendar = Calendar.getInstance();
                Date date = calendar.getTime();
                String dateStringParse = sdf.format(date);

                br.setCreateDate(dateStringParse);
                br.setType(4);
                br.setUserId(Long.valueOf(split[i]));
                br.setBonusName("代理分佣");
                br.setFromId(cancelOrSubmitDto.getUserId());
                br.setAmount(xgbGrabOrdersRecord.getCommission().multiply(new BigDecimal("0.04")));
            }
            bonusRecordMapper.insert(br);
        }
        row = row + bonusRecordMapper.insert(bonusRecord);
        if (row != 3) {
            throw new RuntimeException("提交失败");
        }
        row = row + usersMapper.update(null, new UpdateWrapper<XgbUsers>()
                .eq("id", cancelOrSubmitDto.getUserId())
                .setSql("today_order_num=today_order_num+" + 1));
        if (row != 4) {
            throw new RuntimeException("提交失败");
        }
        result.setMessage("提交成功");
        result.setCode(200);
        return result;
    }


    @Override
    public Result<GrabPageInfoPo> getTodayVictory(QueryParameterDto queryParameterDto) throws Exception {
        log.info("queryParameterDto={}", queryParameterDto);
        Result<GrabPageInfoPo> result = new Result<>();
        if (loginVerification(queryParameterDto.getUserId(), queryParameterDto.getToken())) {
            result.setCode(401);
            result.setMessage("请登录");
            return result;
        }
        XgbAccount xgbAccount = accountMapper.selectOne(new QueryWrapper<XgbAccount>()
                .eq("user_id", queryParameterDto.getUserId()));
        XgbUsers users = usersMapper.selectById(queryParameterDto.getUserId());
        GrabPageInfoPo grabPageInfoPo = new GrabPageInfoPo();
        grabPageInfoPo.setBalance(xgbAccount.getBalance());
        grabPageInfoPo.setYesterdayIncome(xgbAccount.getOrderGrabYesterdayTotalIncome());
        grabPageInfoPo.setTodayOrderNum(users.getTodayOrderNum());
        grabPageInfoPo.setTodayRobbedAmount(xgbAccount.getOrderGrabTodayTotalIncome());
        result.setCode(200);
        result.setMessage("成功");
        result.setData(grabPageInfoPo);
        return result;
    }


    private boolean loginVerification(Long userId, String token) {
        String redisToken = redisTemplate.opsForValue().get("token:" + userId);
        return (StringUtils.isEmpty(redisToken) || !redisToken.equalsIgnoreCase(token));
    }

    private Integer getIndexOf(Integer size) {
        return (int) (Math.random() * (size - 1));
    }


    private long getRandom(long min, long max) {
        return (long) (Math.random() * (max - min) + min);
    }
}
